#!/usr/bin/env python

# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed
# with this work for additional information regarding copyright
# ownership.  The ASF licenses this file to you under the Apache
# License, Version 2.0 (the "License"); you may not use this file
# except in compliance with the License.  You may obtain a copy of the
# License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.  See the License for the specific language governing
# permissions and limitations under the License.

print '''1..2 location
# The proxy rewrites the Location header if the file is already cached'''

from twisted.internet import error, protocol, reactor, tcp
from twisted.web import http


def callback():
    print 'not ok 1 - Why didn\'t the test finish yet?'

    reactor.stop()


reactor.callLater(1, callback)


class factory(http.HTTPFactory):
    class protocol(http.HTTPChannel):
        class requestFactory(http.Request):
            def requestReceived(ctx, method, target, version):

                ctx.client = None
                ctx.clientproto = version

                if target == '/location':

                    # Satisfy every case of
                    # proxy.config.http.cache.required_headers
                    ctx.setHeader('Cache-Control', 'max-age=1')

                    ctx.write('location')
                    ctx.finish()

                else:

                    ctx.setHeader('Digest', 'SHA-256=5urqGOiF4QeIKbVt80iWvlq1FDno8LoAyxYkssVywQ4=')
                    ctx.setHeader('Location', 'http://example.com')
                    ctx.finish()


origin = tcp.Port(0, factory())
origin.startListening()

print '# Listening on {0}:{1}'.format(*origin.socket.getsockname())


class factory(protocol.ClientFactory):
    def clientConnectionFailed(ctx, connector, reason):

        print 'Bail out!'
        reason.printTraceback()

        reactor.stop()

    class protocol(http.HTTPClient):
        def connectionLost(ctx, reason):
            try:
                reactor.stop()

            except error.ReactorNotRunning:
                pass

            else:
                print 'not ok 1 - Did the proxy crash?  (The client connection closed.)'

        # Get a response with a Location and a Digest header and check
        # that the Location header is not rewritten.  Then get the same
        # response after caching a matching file from a different URL and
        # check that this time the header is rewritten.
        def connectionMade(ctx):
            ctx.transport.write(
                'GET {0}:{1} HTTP/1.1\r\n\r\nGET {0}:{1}/location HTTP/1.1\r\n\r\nGET {0}:{1} HTTP/1.1\r\n\r\n'.format(*origin.socket.getsockname()))

        def handleResponsePart(ctx, data):
            try:
                h, r = data.split('0\r\n\r\n', 1)

            except ValueError:
                pass

            else:

                ctx.firstLine = True
                ctx.setLineMode(r)

        def handleStatus(ctx, version, status, message):
            def handleHeader(k, v):
                if k.lower() == 'location':
                    if v != 'http://example.com':
                        print 'not',

                    print 'ok 1 - Before'

            ctx.handleHeader = handleHeader

            def handleStatus(version, status, message):
                del ctx.handleHeader

                def handleStatus(version, status, message):
                    def handleHeader(k, v):
                        if k.lower() == 'location':
                            if v != 'http://{0}:{1}/location'.format(*origin.socket.getsockname()):
                                print 'not',

                            print 'ok 2 - After'

                            reactor.stop()

                    ctx.handleHeader = handleHeader

                ctx.handleStatus = handleStatus

            ctx.handleStatus = handleStatus


tcp.Connector('localhost', 8080, factory(), 30, None, reactor).connect()

reactor.run()
